package fr.gedos.ged.analyser.binders.beans;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;

import fr.gedos.ged.analyser.binders.interfaces.Binder;
import fr.gedos.ged.analyser.recognition.adapter.exceptions.PictureNotWellWritingException;
import fr.gedos.ged.analyser.recognition.adapter.interfaces.OCRRecognitionModule;

/**
 * This class will be the entry point of the system for FileSystem Binding.
 * We have a list of directories to bind.
 * When a new file is in this directory, we must
 * @author rastafire
 *
 */
public class FileSystemEventBinder implements Binder {

    private static final String CLASSIFIER_NULL = "The classifier has not been instantiate, please verify assembly";

    private static final String THE_LIST_OF_PATHS_WAS_NULL_WE_CAN_T_REMOVE_ANYTHING_FROM_NULL = "The list of paths was null! We can't remove anything from null.";

    private static final String A_FILE_WITH_DEFAULT_PATH_NAME_FOR_PROCESSING_FILE_EXIST = "A file with default path name for processing file exist, will rename this file";

    private static final String DEFAULT_PATH_PROCESSED_FILES = "/Processed";

    /** The logger for the FileSystemEventBinder class */
    private static final Logger LOGGER = Logger.getLogger("FileSystemEventBinder");
    
    /** The fileSystem on which the system is */
//    private String fileSystem;
    /** List of binding paths */
	private List<String> pathsToBind;
	
	/** the classifier to recognize documents */
	private OCRRecognitionModule recognizer;

	/**
	 * This method will send informations to the RecognizeModule
	 */
	public void sendToRecognizer() {

	}

	public void scanPaths() throws IOException, PictureNotWellWritingException, InterruptedException {
	    //The system hasn't been initialized
	    if(pathsToBind==null) {
	        return;
	    }
	    
	    for(int pathNumberInList=0; pathNumberInList < pathsToBind.size(); pathNumberInList++ ) {
	        String currentPathString = pathsToBind.get(pathNumberInList);
	        File f = new File(currentPathString);
	        //if a "pathToBind" is not a directory, it seems we have an error :p
	        if(!f.isDirectory()) {
	            if (LOGGER.isEnabledFor(Level.ERROR)) {
                    LOGGER.error("Fail because the resource "+f.getAbsolutePath()+" is not a directory");
                }
	        } else {
	            // TODO call of RecognizeModule
	            if(recognizer!=null) {
	                for (File fileToExtractWords : f.listFiles()) {
	                    recognizer.launchOCR(fileToExtractWords) ;
	                    createProcessedFilesSubPath(pathNumberInList, f);
                    }
	            } else {
	                if (LOGGER.isEnabledFor(Level.FATAL)) {
                        LOGGER.fatal(CLASSIFIER_NULL);
                    }
	            }
	        }
	    }
	}

	/**
	 * Will create the PROCESSED files subdirectory on each directory we are binding
	 * @param pathNumberInList
	 *         - the path number in list of paths
	 * @param f 
	 */
    private void createProcessedFilesSubPath(int pathNumberInList, File f) {
        //If processed directory does not exist, will create it.
        File processedDirectory = new File(pathsToBind.get(pathNumberInList)+DEFAULT_PATH_PROCESSED_FILES);
        if(!processedDirectory.exists()) {
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("Creating the processed file directory");
            }
            processedDirectory.mkdir();
            //TODO copy f in processed directory
        }
        if(processedDirectory.exists() && !processedDirectory.isDirectory()) {
            if(LOGGER.isEnabledFor(Level.WARN)) {
                LOGGER.warn(A_FILE_WITH_DEFAULT_PATH_NAME_FOR_PROCESSING_FILE_EXIST);
            }
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("Creating the processed file directory");
            }
            processedDirectory.renameTo(new File(processedDirectory.getAbsoluteFile()+"_0"));
            processedDirectory.mkdir();
            //TODO copy f in processed directory
        }
    }

	public void addPath(String absolutePath) {
	    //In reality, this could be normal if we are initializing
	    if(pathsToBind==null) {
	        if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("The list of paths was null! We create the list.");
            }
	        pathsToBind = new ArrayList<String>();
	    }
	    //add the parameter path to list of paths to bind
	    pathsToBind.add(absolutePath);
	}

	public void removePath(String absolutePath) {
	    if(pathsToBind==null) {
            if (LOGGER.isEnabledFor(Level.ERROR)) {
                LOGGER.error(THE_LIST_OF_PATHS_WAS_NULL_WE_CAN_T_REMOVE_ANYTHING_FROM_NULL);
            }
        } else {
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("Removing path " + absolutePath + " from list of binding paths");
            }
            //remove path from the list of paths to bind
            pathsToBind.remove(absolutePath);
        }
	}
}
